(use-modules
 (fibers)
 (fibers channels)
 (ice-9 match))

;; Define a procedure to run in a fiber.
(define fiber1-proc
  (lambda (in-chan out-chan)
    ;; Some procedure to perform work.
    (define perform-calculation
      (lambda (data)
        (sleep data)
        (simple-format #f "slept for ~as\n" data)))
    ;; Look for mesages.
    (let loop ()
      (match
          ;; Write arguments to the current output port, and return the last
          ;; argument. This will get the message received and write to current
          ;; output port an information, that the get-message procedure was
          ;; called.
          (pk 'fiber1-proc-called-get-message
              (get-message in-chan))
        ;; Match anything coming in and give it to the procedure which shall
        ;; calculate the response message.
        [msg (put-message out-chan (perform-calculation msg))])
      ;; Continue looking for messages.
      (loop))))

(run-fibers
 (lambda ()
   (let ((fiber1-in-chan (make-channel))
         (fiber1-out-chan (make-channel)))
     ;; Spawn a fiber to run fiber1-proc, which internally looks for messages on
     ;; its in-channel.
     (spawn-fiber
      (lambda ()
        (fiber1-proc fiber1-in-chan fiber1-out-chan)))
     ;; Send a mssage to the fiber.
     (put-message fiber1-in-chan
                  10)
     ;; Look for the answer on the out-channel of the fiber.
     (display
      (simple-format
       #f "~a\n" (pk 'main-thread-called-peek
                     (get-message fiber1-out-chan)))))))
